package cc.iotkit.manager.task;

import cc.iotkit.common.thing.ThingModelMessage;
import cc.iotkit.data.manager.IDeviceHourlyReportData;
import cc.iotkit.data.manager.IDeviceInfoData;
import cc.iotkit.model.device.DeviceHourlyReport;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.temporal.IThingModelMessageData;
import cn.hutool.json.JSONUtil;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 同步所有设备的工作时长，每小时同步
 */
@Component
public class SyncWorkingTimesHourly {
    @Autowired
    private IDeviceInfoData deviceInfoData;
    @Autowired
    private IDeviceHourlyReportData deviceHourlyReportData;

    @Autowired
    private IThingModelMessageData thingModelMessageData;
    @Autowired
    private StringRedisTemplate redisTemplate;
    private static Logger logger = LoggerFactory.getLogger(SyncWorkingTimesHourly.class);
    private String LastTimeCacheKey="sync:workingtime_hourly";
    Date startTime = null;
    Date endTime = null;

    @XxlJob("SyncWorkingtimesHourly")
    public void run() throws Exception {
        logger.info("xxl-job:running SyncWorkingtimesHourly...");
        //设置当前日期
        //SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();

        while (true){
            String lastTime= getLastTime();
            startTime = Date.from(LocalDateTime.parse(lastTime).atZone(ZoneId.systemDefault()).toInstant());
            c.setTime(startTime);
            c.add(Calendar.HOUR,1);
            endTime = c.getTime();

            //是否大于当前时间
            if(endTime.getTime()<new Date().getTime()){
                 try {
                     List<DeviceInfo> list= deviceInfoData.findAll();
                     List<DeviceHourlyReport> reports=new ArrayList<>();
                     for(DeviceInfo info : list) {
                         List<ThingModelMessage> messageList = thingModelMessageData.findWorkingStatusLog(info.getDeviceId(), startTime.getTime(), endTime.getTime());
                         if (messageList.size() > 0) {
                             Long onlineSecends = this.getOnlineSecends(messageList);
                             DeviceHourlyReport report = new DeviceHourlyReport();
                             report.setWorkingTimes(onlineSecends);
                             report.setReportDate(endTime);
                             report.setHour(String.valueOf(endTime.getHours()));
                             report.setDeviceId(info.getDeviceId());
                             reports.add(report);
                         } else {
                             //判断是否连续工作几个小时
                             //如果当前无工作状态，查询最近一次的工作状态，如果为工作中，补充开始时间
                             messageList = thingModelMessageData.findLastWorkingStatus(startTime.getTime(), info.getDeviceId());
                             if (messageList.size() > 0) {
                                 String status = JSONUtil.parse(messageList.get(0).getData()).getByPath("status").toString();
                                 if (status.equals("1")) {
                                     messageList.get(0).setTime(startTime.getTime());
                                     Long onlineSecends = this.getOnlineSecends(messageList);
                                     DeviceHourlyReport report = new DeviceHourlyReport();
                                     report.setWorkingTimes(onlineSecends);
                                     report.setReportDate(endTime);
                                     report.setHour(String.valueOf(endTime.getHours()));
                                     report.setDeviceId(info.getDeviceId());
                                     reports.add(report);
                                 }
                             }

                         }

                         deviceHourlyReportData.batchSave(reports);

                     }
                }
                catch (Exception e){
                    logger.info("xxl-job-error:"+e.getMessage());
                    XxlJobHelper.log(e);
                    XxlJobHelper.handleFail();
                }

                lastTime=LocalDateTime.ofInstant(endTime.toInstant(), ZoneId.systemDefault()).toString();
                this.setLastTime(lastTime);
                logger.info("xxl-job:running SyncWorkingtimesHourly finished");
            }else{
                break;
            }
        }



    }

    private Long getOnlineSecends(List<ThingModelMessage> messageList){
        //判断第一条，是否需要填充登入
        ThingModelMessage message= messageList.get(0);
        String status= JSONUtil.parse(message.getData()).getByPath("status").toString();

        //补充开始时间
        if(status.equals("0")){
            ThingModelMessage msg=new ThingModelMessage();
            msg.setDeviceId(message.getDeviceId());
            msg.setTime(startTime.getTime());
            msg.setData("{\"status\":\"1\"}");
            messageList.add(0,msg);
        }
        //判断最后一条，是否需要填充登出
        message= messageList.get(messageList.size()-1);
        String status1= JSONUtil.parse(message.getData()).getByPath("status").toString();
        if(status1.equals("1")){
            ThingModelMessage msg=new ThingModelMessage();
            msg.setDeviceId(message.getDeviceId());
            msg.setTime(endTime.getTime());
            msg.setData("{\"status\":\"0\"}");
            messageList.add(msg);
        }
        Long onlineSeconds=0L;
        Long onlineTime=0L;
        String lastStatus="";
        //计算在线时间
        for(ThingModelMessage row: messageList){
            String status2= JSONUtil.parse(row.getData()).getByPath("status").toString();
            if(lastStatus.equals(status2)){
                continue;
            }else{
                lastStatus=status2;
            }
            if(status2.equals("1")){
                onlineTime=row.getTime();
            }
            else{
                onlineSeconds+=row.getTime()-onlineTime;
            }
        }

        return onlineSeconds/1000;
    }


    public String getLastTime() {
        Object last = redisTemplate.opsForValue().get(LastTimeCacheKey);
        if(ObjectUtils.isEmpty(last)){
            Calendar c = Calendar.getInstance();
            return LocalDateTime.of(c.get(Calendar.YEAR),c.get(Calendar.MONTH)+1,c.get(Calendar.DAY_OF_MONTH),0,0,0,0).toString();
        }
        return last.toString();
    }

    public void setLastTime(String lastTime) {
        redisTemplate.opsForValue().set(LastTimeCacheKey, lastTime);
    }
}
